﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using AOT.Game.Timer;
using Net.Msg;
using Net.Public.Client;
using Net.Public.EventSystem;
using Net.Public.Helper;
using Net.Public.Msg;
using Net.Runtime.Base;

namespace Net.Public.Server
{
    public class RpcServer : BaseRpc
    {
        private readonly int CHECK_HEART_TIME = 5;
        private long _chectHeartTimer = -1;
        private WServer _wServer;
        public int ClientNum => _wServer == null ? 0 : _wServer.ClientNum;
        public Action<RpcServer> updateAction;
        private ScriptTimer _timer;
        public override void OnStart(ScriptTimer _timer, string ip, int port, int maxConnectNum)
        {
            this._timer = _timer;
            _wServer = new WServer(ip, port, maxConnectNum);
            //心跳
            RpcEventSystem.Instance.RegisterMsg(EMsgType.HeartMsg, (msg) =>
            {
                HeartMsg heartMsg = msg as HeartMsg;
                UpdateHeart(heartMsg.ClientId, true);
            });
            _chectHeartTimer = _timer.DoThingPeriod(CHECK_HEART_TIME, () =>
            {
                var clientDic = _wServer.clientDic;
                List<int> removeIdList = new();
                foreach (var id in clientDic.Keys)
                {
                    var client = clientDic[id];
                    if (client.IsOnline == false)
                    {
                        removeIdList.Add(id);
                    }
                    UpdateHeart(id,false);
                }
                foreach (var removeId in removeIdList)
                {
                    RemoveClient(removeId);
                }
            });
            base.OnStart(_timer, ip, port, maxConnectNum);
            _wServer.Start();
        }

        public override void OnUpdate()
        {
            base.OnUpdate();
            updateAction?.Invoke(this);
        }

        public void RemoveClient(int id) => _wServer.RemoveClient(id);
        public void SendMsgToClient(int id, BaseMsg msg) => _wServer.SendMsgToClient(id, msg);
        public void BroadcastMsgToClients(BaseMsg msg) => _wServer.BroadcastMsgToClients(msg);

        public void OnClose()
        {
            _wServer.Dispose();
            this._timer.TryStopTimerById(this._chectHeartTimer);
        }

        private void UpdateHeart(int id, bool isHeart)
        {
            if (_wServer.clientDic.TryGetValue(id, out ClientSockt clientSockt))
                clientSockt.IsOnline = isHeart;
        }
    }
}